#include <stdio.h>
#include <string>
#include <vector>
#include <unistd.h>
#include <functional>
#include <algorithm>

#include "thread/Latch.h"
#include "thread/current_thread.h"
#include "thread/Thread.h"

class Test
{
 public:
  Test(int numThreads)
    : latch_(numThreads),
      threads_{}
  {
    for (int i = 0; i < numThreads; ++i)
    {
      char name[32];
      snprintf(name, sizeof name, "work thread %d", i);
      threads_.push_back(
              std::make_shared<Thread>(std::bind(&Test::threadFunc, this), std::string(name)));
    }
    
    for (const auto &t : threads_)
      t->start();
  }

  void wait()
  {
    latch_.wait();
  }

  void joinAll()
  {
    for (const auto &t : threads_)
      t->join();
  }

 private:

  void threadFunc()
  {
    sleep(3);
    latch_.count_down();
    printf("tid=%d, %s started\n",
           CurrentThread::tid(),
           CurrentThread::thread_name());

    

    printf("tid=%d, %s stopped\n",
           CurrentThread::tid(),
           CurrentThread::thread_name());
  }

  Latch latch_;
  std::vector<std::shared_ptr<Thread>> threads_;
};

int main()
{
  printf("pid=%d, tid=%d\n", ::getpid(), CurrentThread::tid());
  Test t(3);
  t.wait();
  printf("pid=%d, tid=%d %s running ...\n", ::getpid(), CurrentThread::tid(), CurrentThread::thread_name());
  t.joinAll();

  printf("number of created threads %d\n", Thread::TOTAL().load());
}


